package com.ecnu.sei.app.course;

import java.util.Set;

import com.ecnu.sei.app.Scheduler;
import com.ecnu.sei.app.resources.Classroom;
import com.ecnu.sei.app.teacher.ITeacher;
import com.ecnu.sei.app.teacher.Official;
import com.ecnu.sei.app.util.Utils.DayHour;

/*
 *  universal rules for all kinds of courses:
 * 
 *  1. studentNum >= 60 => 3 proctors (one prime, two vice)
 *     studentNum <  60 => 2 proctors (one prime, one vice)
 *  2. normally, a course's lecturer will be the prime proctor, choose another one
 *     only if a teacher is not available for being lecturers for more than one course
 *  3. one backup proctor, from those who has proctored below-average number of courses in one semester  
 */

public abstract class AbstractCourse implements ICourse {

  protected CourseInfo info = null;

  protected Scheduler scheduler = Scheduler.getScheduler();

  public AbstractCourse() {}

  public AbstractCourse(CourseInfo info) {
    this.info = info;
  }

  public AbstractCourse(String courseId, String courseName, String className, ITeacher teacher, 
      int dayOfWeek, DayHour dayHour, int studentNum, Classroom classroom) {
    this.info = new CourseInfo(courseId, courseName, className, 
        teacher, dayOfWeek, dayHour, studentNum, classroom); 
  }

  public CourseInfo getCourseInfo() {
    return info;
  }

  public void SetCourseInfo(CourseInfo info) {
    this.info = info;
  }

  @Override
  public boolean hasEnoughProctors() {
    ExamInfo examInfo = info.getExamInfo();

    Set<ITeacher> proctors = examInfo.getProctor();
    if (null == proctors || proctors.size() < examInfo.getProctorNum()) {
      return false;
    } else {
      return true;
    }
  }

  @Override
  public boolean addProctor(ITeacher teacher) {
    ExamInfo examInfo = info.getExamInfo();
    Set<ITeacher> proctors = examInfo.getProctor();

    if (!proctors.contains(teacher)) {
      if (teacher.isAvailableFor(this)) {
        proctors.add(teacher);
        return true;
      }
    }

    return false;
  }

  @Override
  public boolean setPatrol(Official patrol) {
    if (patrol.isAvailableFor(this)) {
      ExamInfo examInfo = info.getExamInfo();
      examInfo.setPatrol(patrol);
      patrol.addProctor(this);
      return true;
    } else {
      return false;
    }

  }

  @Override
  public boolean setBackup(ITeacher backup) {
    if (backup.isAvailableFor(this)) {
      ExamInfo examInfo = info.getExamInfo();
      examInfo.setBackup(backup);
      backup.addProctor(this);
      return true;
    } else {
      return false;
    }
  }
}
